package com.soxing.webrain.brush.controller;

import com.mathworks.toolbox.javabuilder.*;
import com.soxing.webrain.brush.api.IUserEegHandleService;
import com.soxing.webrain.brush.api.zip.IReadZipStructService;
import com.soxing.webrain.brush.common.util.AddressDesUtil;
import com.soxing.webrain.brush.dao.service.ICombsUserFileService;
import com.soxing.webrain.brush.dao.service.ICombsUserUploadFileService;
import com.soxing.webrain.brush.domain.view.Eeg;
import com.soxing.webrain.brush.domain.view.EegDTO;
import com.soxing.webrain.brush.domain.view.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import us.hebi.matlab.mat.format.Mat5;
import us.hebi.matlab.mat.format.Mat5File;
import us.hebi.matlab.mat.types.Cell;
import us.hebi.matlab.mat.types.Char;
import us.hebi.matlab.mat.types.Matrix;
import us.hebi.matlab.mat.types.Struct;
import wb_loadEEG.WbPopLoadSet;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.List;


//http://localhost:18081/myview/view
//@RestController
//@RequestMapping("/myview")
@Slf4j
@RestController("/myEEGView")     //restControlller路径上可以不用写myview
@Api(value = "eeg画图管理", tags = {"eeg画图管理"})
public class MyViewController2 {

    @Resource
    private ICombsUserFileService userFileService;
    @Resource
    private ICombsUserUploadFileService userUploadFileService;
    @Resource
    private IUserEegHandleService userEegHandleService;
    @Resource
    private IReadZipStructService readZipStructService;

    @GetMapping("/view2")
    @ApiOperation(value = "Eeg数据读取")
    public Eeg getIdFileList2(@RequestParam(value = "fullpath", required = false) String fullpath, @RequestParam(value = "star", required = false) Integer star,
                             @RequestParam(value = "end", required = false) Integer end, HttpServletRequest request) {
        if (fullpath == "0") {
            return null;
        }

        String path = AddressDesUtil.getDecryptString(fullpath);
        return userEegHandleService.packageData(star, end, path);
    }

    @GetMapping("eegshow1")
    public R Test1(@RequestParam(value = "star", required = false) Integer star,
                  @RequestParam(value = "end", required = false) Integer end,
                  @RequestParam(value = "path", required = false) String path)
    {
        EegDTO eegDTO = new EegDTO();
        try{
//            File file = new File(path);
            Mat5File file = Mat5.readFromFile(path);
            Struct eeg = file.getStruct("feedback_results").getStruct("EEG_prepro");
//            Matrix srate = file.getMatrix("srate");
            Matrix srate = eeg.getMatrix("srate");
            double[] srated = new double[1];
            Double aDouble1 = Double.valueOf(srate.toString());
            srated[0] = aDouble1;
            eegDTO.setSrate(srated);

//            Matrix srateOld = file.getMatrix("srateOld");
//            eegDTO.setSrateOld(new double[]{Double.parseDouble(srateOld.toString())});
            eegDTO.setSrateOld(eegDTO.getSrate());

            Matrix data = eeg.getMatrix("data");
            List<List<Double>> data1 = new ArrayList<>();
            for (int i = 0; i < data.getNumRows(); i++) {
                List<Double> list = new ArrayList<>();
                for (int j = (int) (star * aDouble1); j < end * aDouble1; j++) {
                    if (j == data.getNumCols()) {
                        break;
                    } else {
                        list.add(data.getDouble(i, j));
                    }
                }
                data1.add(list);
            }
            eegDTO.setData(data1);

            Char ref = eeg.getChar("ref");
            eegDTO.setRef(String.valueOf(ref));

            Cell event_type = eeg.getCell("event_type");
            List<String> list2 = new ArrayList<>();
            for (int i = 0; i < event_type.getNumCols(); i++) {
                list2.add(String.valueOf(event_type.get(i)));
            }
            eegDTO.setEvent_type(list2);

            Matrix m1  = eeg.getMatrix("event_latency");
            List<Double> list1 = new ArrayList<>();
            for (int i = 0; i < m1.getNumCols(); i++) {
                double aDouble = m1.getDouble(i);
                list1.add(aDouble);
            }
            double[] doubles = new double[list1.size()];
            for (int i = 0; i < list1.size(); i++) {
                doubles[i] = list1.get(i);
            }
            eegDTO.setEvent_latency(doubles);

            Char labels = eeg.getChar("labels");
            List<String> list3 = new ArrayList<>();
//            for (int i = 0; i < labels.getNumCols(); i++) {
//                list3.add(String.valueOf(labels.getChar(i)));
//            }
            //因为label不是单个字符，而是字符串，所以做了一下修改
            for (int i = 0; i < labels.getNumRows(); i++) {
                list3.add(String.valueOf(labels.getRow(i)));
            }
            eegDTO.setLabels(list3);

            Matrix m4 = eeg.getMatrix("theta");
            List<Double> list4 = new ArrayList<>();
            for (int i = 0; i < m4.getNumCols(); i++) {
                double aDouble = m4.getDouble(i);
                list4.add(aDouble);
            }
            double[] doubles4 = new double[list4.size()];
            for (int i = 0; i < list4.size(); i++) {
                doubles4[i] = list4.get(i);
            }
            eegDTO.setTheta(doubles4);

            Matrix m5 = eeg.getMatrix("radius");
            List<Double> list5 = new ArrayList<>();
            for (int i = 0; i < m5.getNumCols(); i++) {
                double aDouble = m5.getDouble(i);
                list5.add(aDouble);
            }
            double[] doubles5 = new double[list5.size()];
            for (int i = 0; i < list5.size(); i++) {
                doubles5[i] = list5.get(i);
            }
            eegDTO.setRadius(doubles5);

            Matrix xmin = eeg.getMatrix("xmin");
            double[] xmind = new double[1];
            xmind[0] = Double.valueOf(xmin.toString());
            eegDTO.setXmin(xmind);

            Matrix xmax = eeg.getMatrix("xmax");
            double[] xmaxd = new double[1];
            xmaxd[0] = Double.valueOf(xmax.toString());
            eegDTO.setXmax(xmaxd);

            Matrix trials = eeg.getMatrix("trials");
            double[] trialsd = new double[1];
            trialsd[0] = Double.valueOf(trials.toString());
            eegDTO.setTrials(trialsd);

//            Matrix m6 = eeg.getMatrix("times");
//            List<String> list6 = new ArrayList<>();
//            for (int i = 0; i < m6.getNumCols(); i++) {
//                list6.add(String.valueOf(m6.getDouble(i)));
//            }
//
//            List time = new ArrayList();
//            for (int i = 0; i <= 5 * srated[0]; i++) {
//                time.add(star + i  / srated[0]);
//            }
//
//            eegDTO.setTime(time);
            eegDTO.setStart(star);
            eegDTO.setEnd(end);
            data = eeg.getMatrix("erp");
            data1 = new ArrayList<>();
            for (int i = 0; i < data.getNumRows(); i++) {
                List<Double> list = new ArrayList<>();
                for (int j = 0; j < (xmaxd[0] - xmind[0]) * aDouble1; j++) {
                    if (j == data.getNumCols()) {
                        break;
                    } else {
                        list.add(data.getDouble(i, j));
                    }
                }
                data1.add(list);
            }
            eegDTO.setErp(data1);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return R.ok().data("eeg",eegDTO);
    }

    @GetMapping("eegshow")
    public R Test(@RequestParam(value = "star", required = false) Integer star,
                  @RequestParam(value = "end", required = false) Integer end,
                  @RequestParam(value = "path", required = false) String path)
    {
        //star表示脑电波形的开始时间，end表示脑电波形结束时间，path表示脑电的储存位置

        int starttime = star;
        int endtime = end;
        System.out.println(endtime);
        WbPopLoadSet w = null;
        Eeg eeg = new Eeg();
        try {
            w = new WbPopLoadSet();
        } catch (MWException e) {
            e.printStackTrace();
        }
        Object[] result = null;

        try {
            result = w.wb_loadEEG(18, path);

            MWNumericArray temp = (MWNumericArray) result[1];
            double[][] data = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[2];
            double[][] srate = (double[][]) temp.toDoubleArray();

            String ref = (String) result[3].toString();

            MWCellArray temp1 = (MWCellArray) result[4];
            String event_type = temp1.toString();

            temp = (MWNumericArray) result[5];
            double[][] event_latency = (double[][]) temp.toDoubleArray();

            MWCharArray temp2 = (MWCharArray) result[6];
            String labels = (String) temp2.toString();

            temp = (MWNumericArray) result[7];
            double[][] sph_radius = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[8];
            double[][] sph_theta = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[9];
            double[][] phi = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[10];
            double[][] theta = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[11];
            double[][] radius = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[15];
            double[][] xmin = (double[][]) temp.toDoubleArray();

            temp = (MWNumericArray) result[16];
            double[][] xmax = (double[][]) temp.toDoubleArray();

            List<List<Double>> groupdata = new ArrayList<List<Double>>();
            for (int i = 0; i < data.length; i++) {
                List datas = new ArrayList();
                int s = (int) (1000 / srate[0][0]);
                for (int j = (int) (starttime * srate[0][0]); j < endtime * srate[0][0]; j++) {
                    if (j == data[0].length) {
                        break;
                    } else {
                        datas.add(data[i][j]);
                    }

                }
                groupdata.add(datas);
            }

            List<String> grouplabel = new ArrayList();
            if (labels != null) {
                grouplabel = formatData(labels);
            } else {
                for (int i = 1; i < data.length; i++) {
                    grouplabel.add(i + "");
                }
            }

            if (event_type.contains("[")) {
                String[] tp = event_type.split("[\\[\\]]");
                //------- 对label进行整理  定义集合
                List<String> tp1 = new ArrayList();
                for (int i = 0, j = 0; i < tp.length; i++) {
                    if (i % 2 != 0) {
                        tp1.add(tp[i]);
                    }
                }
                eeg.setEvent_type(tp1);

            } else {

                String[] tp = event_type.split("'"); //la的长度为 labels的二倍
                List<String> tp1 = new ArrayList(); //定义一个用于存放
                for (int i = 1, index = 0; i < tp.length; index++) {
                    tp1.add(tp[i]);
                    i = i + 2;
                }
                eeg.setEvent_type(tp1);
            }

            double[] evtls = null;
            if (event_latency.length != 0) {
                evtls = event_latency[0];
            }else {
                evtls = new double[]{1};
            }
            double[] sraten = srate[0];
            double[] thetan = null;
            if (theta.length != 0) {
                thetan = theta[0];
            }
            double[] radiusn = null;
            if (radius.length != 0) {
                radiusn = radius[0];
            }
            double[] xminn = xmin[0];
            double[] xmaxn = xmax[0];

            List time = new ArrayList();
            for (int i = 0; i <= 5 * srate[0][0]; i++) {
                time.add(starttime + 0.001 * i * 1000 / srate[0][0]);
            }
            // ============== 数据存储
            eeg.setData(groupdata);
            eeg.setSrate(sraten);
            eeg.setRef(ref);
            eeg.setEvent_latency(evtls);
            eeg.setLabels(grouplabel);
            eeg.setTheta(thetan);
            eeg.setRadius(radiusn);
            eeg.setXmin(xminn);
            eeg.setXmax(xmaxn);
            eeg.setTime(time);

        } catch (MWException e) {
            e.printStackTrace();
        }finally{
            MWArray.disposeArray(result);
        }
        return R.ok().data("eeg",eeg);
        //放回Eeg类的实例给前端，前端解析之后便能显示出波形
    }
    public List<String> formatData(String labels) {
        String[] la = labels.split("\n");
        List<String> grouplabel = new ArrayList();
        for (int index = 0; index < la.length; index++) {
            grouplabel.add(la[index]);
        }
        return grouplabel;
    }
}
